<script lang="ts" setup>
import type { Rule } from 'ant-design-vue/es/form';

import type { InfraConfigApi } from '#/api/infra/config';

import { onMounted, ref } from 'vue';

import { confirm, Page } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons';

import {
  Button,
  Card,
  Form,
  InputNumber,
  message,
  Select,
  Space,
  Switch,
} from 'ant-design-vue';

import { listIgnoreTenant, updateBatchIgnoreTenant } from '#/api/infra/config';

// 定义安全配置类型
interface LoginConfig {
  LOGIN_SAME_COUNT?: InfraConfigApi.Config;
  LOGIN_SMS_CODE_SEND_COUNT?: InfraConfigApi.Config;
  LOGIN_SMS_CODE_SEND_TIME?: InfraConfigApi.Config;
  LOGIN_SMS_CODE_SEND_LOCK?: InfraConfigApi.Config;
  LOGIN_REGISTER_ENABLED?: InfraConfigApi.Config;
  LOGIN_REGISTER_AUTH?: InfraConfigApi.Config;
  LOGIN_TWO_FACTOR_TIME?: InfraConfigApi.Config;
  LOGIN_TWO_FACTOR_TYPE?: InfraConfigApi.Config;
  LOGIN_CAPTCHA_ENABLED?: InfraConfigApi.Config;
  LOGIN_TWO_FACTOR_ENABLED?: InfraConfigApi.Config;
}
const form = ref<any>({
  LOGIN_SAME_COUNT: 0,
  LOGIN_SMS_CODE_SEND_COUNT: 3,
  LOGIN_SMS_CODE_SEND_TIME: 60,
  LOGIN_SMS_CODE_SEND_LOCK: 30,
  LOGIN_REGISTER_ENABLED: 0,
  LOGIN_REGISTER_AUTH: 0,
  LOGIN_TWO_FACTOR_TIME: 15,
  LOGIN_TWO_FACTOR_TYPE: 105,
  LOGIN_CAPTCHA_ENABLED: 1,
  LOGIN_TWO_FACTOR_ENABLED: 0,
});
const defaultform = ref<any>({
  LOGIN_SAME_COUNT: 0,
  LOGIN_SMS_CODE_SEND_COUNT: 3,
  LOGIN_SMS_CODE_SEND_TIME: 60,
  LOGIN_SMS_CODE_SEND_LOCK: 30,
  LOGIN_REGISTER_ENABLED: 0,
  LOGIN_REGISTER_AUTH: 0,
  LOGIN_TWO_FACTOR_TIME: 15,
  LOGIN_TWO_FACTOR_TYPE: 105,
  LOGIN_CAPTCHA_ENABLED: 1,
  LOGIN_TWO_FACTOR_ENABLED: 0,
});
const oldform = ref<any>({
  LOGIN_SAME_COUNT: 0,
  LOGIN_SMS_CODE_SEND_COUNT: 3,
  LOGIN_SMS_CODE_SEND_TIME: 60,
  LOGIN_SMS_CODE_SEND_LOCK: 30,
  LOGIN_REGISTER_ENABLED: 0,
  LOGIN_REGISTER_AUTH: 0,
  LOGIN_TWO_FACTOR_TIME: 15,
  LOGIN_TWO_FACTOR_TYPE: 105,
  LOGIN_CAPTCHA_ENABLED: 1,
  LOGIN_TWO_FACTOR_ENABLED: 0,
});
// 初始化安全配置
const LoginConfig = ref<LoginConfig>({
  LOGIN_SAME_COUNT: {
    name: '相同账号最大登录人数',
    remark: '相同账号同时间最大登录人数（0-100人），0表示不限制',
  } as InfraConfigApi.Config,
  LOGIN_SMS_CODE_SEND_COUNT: {
    name: '短信最大发送次数',
    remark: '规定时间内登录短信验证码最大发送次数（3-10次）',
  } as InfraConfigApi.Config,
  LOGIN_SMS_CODE_SEND_TIME: {
    name: '短信发送时间（分钟）',
    remark: '计算短信最大发送次数的时间间隔（10-120分钟）',
  } as InfraConfigApi.Config,
  LOGIN_SMS_CODE_SEND_LOCK: {
    name: '超过短信最大发送次数锁定时间（分钟）',
    remark: '超过短信最大发送次数锁定时间（1-1440分钟，即24小时）',
  } as InfraConfigApi.Config,
  LOGIN_REGISTER_ENABLED: {
    name: '是否开启注册',
    remark: '是否开启注册功能',
  } as InfraConfigApi.Config,
  LOGIN_REGISTER_AUTH: {
    name: '是否开启注册审核',
    remark: '注册后是否需要管理员审核',
  } as InfraConfigApi.Config,
  LOGIN_TWO_FACTOR_TIME: {
    name: '双因子认证时间间隔（天）',
    remark: '双因子人才时间间隔（0-30天），0表示每次登录都需要双因子认证',
  } as InfraConfigApi.Config,
  LOGIN_TWO_FACTOR_TYPE: {
    name: '双因子认证类型',
    remark: '双因子认证类型（如：密码+短信，钉钉扫码+短信，钉钉扫码+密码）',
  } as InfraConfigApi.Config,
  LOGIN_CAPTCHA_ENABLED: {
    name: '是否需要登录验证码',
    remark: '登录时是否开启图片验证码校验',
  } as InfraConfigApi.Config,
  LOGIN_TWO_FACTOR_ENABLED: {
    name: '是否开启双因子认证',
    remark: '是否开启双因子认证（如：密码+短信，钉钉扫码+短信，钉钉扫码+密码）',
  } as InfraConfigApi.Config,
});

const rules: Record<string, Rule[]> = {
  LOGIN_SMS_CODE_SEND_COUNT: [{ required: true, message: '请输入值' }],
  LOGIN_SMS_CODE_SEND_TIME: [{ required: true, message: '请输入值' }],
  LOGIN_SMS_CODE_SEND_LOCK: [{ required: true, message: '请输入值' }],
  LOGIN_REGISTER_ENABLED: [{ required: true, message: '请输入值' }],
  LOGIN_SAME_COUNT: [{ required: true, message: '请输入值' }],
  LOGIN_CAPTCHA_ENABLED: [{ required: true, message: '请输入值' }],
  LOGIN_TWO_FACTOR_ENABLED: [{ required: true, message: '请输入值' }],
};
const loading = ref<boolean>(false);
const formRef = ref();
const isUpdate = ref(false);
const queryForm = {
  category: 'LOGIN',
};
// 加载安全配置
const getData = async () => {
  try {
    loading.value = true;
    const data = await listIgnoreTenant(queryForm);
    if (data && data.length > 0) {
      const configList = data.reduce(
        (obj: LoginConfig, option: InfraConfigApi.Config) => {
          obj[option.key] = { ...option, value: Number.parseInt(option.value) };
          form.value[option.key] = Number.parseInt(option.value);
          oldform.value[option.key] = Number.parseInt(option.value);
          return obj;
        },
        {},
      );
      // 根据key 和原有的configList 合并
      LoginConfig.value = { ...LoginConfig.value, ...configList };
    }
    loading.value = false;
  } catch (error) {
    message.error('加载安全配置失败');
    console.error('Failed to load security config:', error);
  }
};

// 保存安全配置
const handleSave = async () => {
  const valid = await formRef.value.validate().catch(() => false);
  if (!valid) return false;
  try {
    await updateBatchIgnoreTenant(
      Object.entries(form.value).map(([key, value]) => {
        return {
          id: LoginConfig.value[key]?.id,
          key,
          value,
          name: LoginConfig.value[key]?.name,
          visible: false,
          category: 'LOGIN',
          type: 1,
          remark: LoginConfig.value[key]?.remark,
        } as InfraConfigApi.Config;
      }),
    );
    await getData();
    message.success('保存成功');
  } catch (error) {
    message.error('保存失败');
    console.error('Failed to save security config:', error);
  }
};

const onResetValue = () => {
  confirm('确认恢复安全配置为默认值吗？')
    .then(async () => {
      await updateBatchIgnoreTenant(
        Object.entries(defaultform.value).map(([key, value]) => {
          return {
            id: LoginConfig.value[key]?.id,
            key,
            value,
            name: LoginConfig.value[key]?.name,
            visible: false,
            category: 'LOGIN',
            type: 1,
            remark: LoginConfig.value[key]?.remark,
          } as InfraConfigApi.Config;
        }),
      );

      message.success({
        content: '恢复成功',
        key: 'action_key_msg_success',
      });
      await getData();
    })
    .catch(() => {});
};
// 修改
const onUpdate = () => {
  isUpdate.value = true;
};

// 取消
const handleCancel = () => {
  form.value = Object.assign({}, oldform.value);
  isUpdate.value = false;
};
// 初始加载配置
onMounted(() => {
  getData();
});
</script>

<template>
  <Page auto-content-height>
    <Card title="登录配置">
      <Form
        ref="formRef"
        :loading="loading"
        :rules="rules"
        :model="form"
        :disabled="!isUpdate"
        label-align="left"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <Form.Item
          :label="LoginConfig.LOGIN_SAME_COUNT.name"
          name="LOGIN_SAME_COUNT"
          :help="LoginConfig.LOGIN_SAME_COUNT.remark"
        >
          <InputNumber
            v-model:value="form.LOGIN_SAME_COUNT"
            :min="0"
            :max="100"
          >
            <template #addonAfter> 人 </template>
          </InputNumber>
        </Form.Item>
        <Form.Item
          :label="LoginConfig.LOGIN_SMS_CODE_SEND_COUNT.name"
          name="LOGIN_SMS_CODE_SEND_COUNT"
          :help="LoginConfig.LOGIN_SMS_CODE_SEND_COUNT.remark"
        >
          <InputNumber
            v-model:value="form.LOGIN_SMS_CODE_SEND_COUNT"
            :min="0"
            :max="10"
          >
            <template #addonAfter> 次 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="LoginConfig.LOGIN_SMS_CODE_SEND_TIME.name"
          name="LOGIN_SMS_CODE_SEND_TIME"
          :help="LoginConfig.LOGIN_SMS_CODE_SEND_TIME.remark"
        >
          <InputNumber
            v-model:value="form.LOGIN_SMS_CODE_SEND_TIME"
            :min="10"
            :max="120"
          >
            <template #addonAfter> 分钟 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="LoginConfig.LOGIN_SMS_CODE_SEND_LOCK.name"
          name="LOGIN_SMS_CODE_SEND_LOCK"
          :help="LoginConfig.LOGIN_SMS_CODE_SEND_LOCK.remark"
        >
          <InputNumber
            v-model:value="form.LOGIN_SMS_CODE_SEND_LOCK"
            :min="1"
            :max="1440"
          >
            <template #addonAfter> 分钟 </template>
          </InputNumber>
        </Form.Item>

        <Form.Item
          :label="LoginConfig.LOGIN_REGISTER_ENABLED.name"
          name="LOGIN_REGISTER_ENABLED"
          :help="LoginConfig.LOGIN_REGISTER_ENABLED.remark"
        >
          <Switch
            v-model:checked="form.LOGIN_REGISTER_ENABLED"
            checked-children="是"
            un-checked-children="否"
            :checked-value="1"
            :un-checked-value="0"
          />
        </Form.Item>
        <Form.Item
          :label="LoginConfig.LOGIN_REGISTER_AUTH.name"
          name="LOGIN_REGISTER_AUTH"
          :help="LoginConfig.LOGIN_REGISTER_AUTH.remark"
        >
          <Switch
            v-model:checked="form.LOGIN_REGISTER_AUTH"
            checked-children="是"
            un-checked-children="否"
            :checked-value="1"
            :un-checked-value="0"
          />
        </Form.Item>
        <Form.Item
          :label="LoginConfig.LOGIN_CAPTCHA_ENABLED.name"
          name="LOGIN_CAPTCHA_ENABLED"
          :help="LoginConfig.LOGIN_CAPTCHA_ENABLED.remark"
        >
          <Switch
            v-model:checked="form.LOGIN_CAPTCHA_ENABLED"
            checked-children="是"
            un-checked-children="否"
            :checked-value="1"
            :un-checked-value="0"
          />
        </Form.Item>
        <Form.Item
          :label="LoginConfig.LOGIN_TWO_FACTOR_ENABLED.name"
          name="LOGIN_TWO_FACTOR_ENABLED"
          :help="LoginConfig.LOGIN_TWO_FACTOR_ENABLED.remark"
        >
          <Switch
            v-model:checked="form.LOGIN_TWO_FACTOR_ENABLED"
            checked-children="是"
            un-checked-children="否"
            :checked-value="1"
            :un-checked-value="0"
          />
        </Form.Item>
        <Form.Item
          :label="LoginConfig.LOGIN_TWO_FACTOR_TYPE.name"
          name="LOGIN_TWO_FACTOR_TYPE"
          :help="LoginConfig.LOGIN_TWO_FACTOR_TYPE.remark"
        >
          <Select v-model:value="form.LOGIN_TWO_FACTOR_TYPE">
            <Select.Option :value="105">账号密码+短信验证码</Select.Option>
            <Select.Option :value="106">账号密码+钉钉扫码</Select.Option>
            <Select.Option :value="107">账号密码+浙政钉扫码</Select.Option>
            <Select.Option :value="108">账号密码+微信扫码</Select.Option>
            <Select.Option :value="109">短信验证码+钉钉扫码</Select.Option>
            <Select.Option :value="110">短信验证码+浙政钉扫码</Select.Option>
            <Select.Option :value="111">短信验证码+微信扫码</Select.Option>
          </Select>
        </Form.Item>
        <Form.Item
          :label="LoginConfig.LOGIN_TWO_FACTOR_TIME.name"
          name="LOGIN_TWO_FACTOR_TIME"
          :help="LoginConfig.LOGIN_TWO_FACTOR_TIME.remark"
        >
          <InputNumber
            v-model:value="form.LOGIN_TWO_FACTOR_TIME"
            :min="0"
            :max="30"
          >
            <template #addonAfter> 天 </template>
          </InputNumber>
        </Form.Item>
        <Space style="margin-bottom: 16px">
          <Button
            type="primary"
            @click="onUpdate"
            v-if="!isUpdate"
            :disabled="false"
          >
            <IconifyIcon icon="lucide:edit" /> 修改
          </Button>
          <Button
            @click="onResetValue"
            style="margin-left: 20px"
            :disabled="false"
            v-if="!isUpdate"
          >
            <IconifyIcon icon="lucide:rotate-ccw" /> 恢复默认
          </Button>
          <Button
            @click="handleSave"
            :disabled="false"
            v-if="isUpdate"
            type="primary"
          >
            <IconifyIcon icon="lucide:save" /> 保存
          </Button>
          <Button
            @click="handleCancel"
            style="margin-left: 20px"
            :disabled="false"
            v-if="isUpdate"
          >
            <IconifyIcon icon="lucide:shield-close" /> 取消
          </Button>
        </Space>
      </Form>
    </Card>
  </Page>
</template>

<style lang="less" scoped>
.form-hint {
  margin-top: 4px;
  font-size: 12px;
  color: #999;
}
</style>
